package com.freexiaoyu.freevideoplay;


import android.graphics.SurfaceTexture;
import android.media.MediaCodec;
import android.media.MediaFormat;
import android.os.Bundle;
import android.util.Log;
import android.view.Surface;
import android.view.TextureView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.nio.ByteBuffer;


public class VideoFFmpegTwoActivity extends AppCompatActivity implements TextureView.SurfaceTextureListener{
    private static final String TAG = "VideoStreaming";
    private DatagramSocket socket;
    private Thread udpReceiverThread;
    private MediaCodec mediaCodec;
    private TextureView textureView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_video_ffmpeg_two);

        textureView = findViewById(R.id.texture_view);
        textureView.setSurfaceTextureListener(this);

    }

    @Override
    public void onSurfaceTextureAvailable(@NonNull android.graphics.SurfaceTexture surface, int width, int height) {
        try {
            setupMediaCodec(surface);
            startUdpServer();
        } catch (IOException e) {
            Log.e(TAG, "Error setting up video streaming", e);
        }
    }

    @Override
    public void onSurfaceTextureSizeChanged(@NonNull  SurfaceTexture surface, int width, int height) {}

    @Override
    public boolean onSurfaceTextureDestroyed(@NonNull SurfaceTexture surface) {
        if (udpReceiverThread != null) {
            udpReceiverThread.interrupt();
        }
        if (mediaCodec != null) {
            mediaCodec.stop();
            mediaCodec.release();
        }
        return true;
    }

    @Override
    public void onSurfaceTextureUpdated(@NonNull  SurfaceTexture surface) {}

    private void setupMediaCodec(SurfaceTexture surfaceTexture) throws IOException {
        // 设置MediaCodec为H.264解码器
        mediaCodec = MediaCodec.createDecoderByType("video/avc");
        MediaFormat format = MediaFormat.createVideoFormat("video/avc", 1080, 720); // 根据实际情况调整分辨率
        mediaCodec.configure(format, new Surface(surfaceTexture), null, 0);
        mediaCodec.start();


    }

    private void startUdpServer() {
        udpReceiverThread = new Thread(() -> {
            byte[] buffer = new byte[1024 * 1024]; // 缓冲区大小应足够大以容纳最大的RTP包
            DatagramPacket packet = new DatagramPacket(buffer, buffer.length);

            try {
                socket = new DatagramSocket(22001);
                while (!Thread.interrupted()) {
                    socket.receive(packet);
                    byte[] data = packet.getData();
                    int length = ((data[0] & 0xFF) << 8) | (data[1] & 0xFF); // 获取RTP包长度

                    if (length > 14 && length <= buffer.length) {
                        byte[] payload = new byte[length - 14];
                        System.arraycopy(data, 14, payload, 0, length - 14); // 去掉前14个字节

                        decodeFrame(payload);
                    }
                }
            } catch (Exception e) {
                Log.e(TAG, "UDP server error", e);
            } finally {
                if (socket != null) {
                    socket.close();
                }
            }
        });
        udpReceiverThread.start();
    }

    private void decodeFrame(byte[] frame) {
        int inputBufferIndex = mediaCodec.dequeueInputBuffer(-1);
        if (inputBufferIndex >= 0) {
            ByteBuffer inputBuffer = mediaCodec.getInputBuffer(inputBufferIndex);
            inputBuffer.clear();
            inputBuffer.put(frame);
            mediaCodec.queueInputBuffer(inputBufferIndex, 0, frame.length, 0, 0);
        }

        MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
        int outputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo, 0);
        while (outputBufferIndex >= 0) {
            mediaCodec.releaseOutputBuffer(outputBufferIndex, true); // 渲染到SurfaceTexture
            outputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo, 0);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (udpReceiverThread != null) {
            udpReceiverThread.interrupt();
        }
        if (mediaCodec != null) {
            mediaCodec.stop();
            mediaCodec.release();
        }
    }
}